package com.znyj.cloud.chain.dispatch;

import com.znyj.cloud.chain.dispatch.annotation.PackageDispatcherMapping;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by gaoliwei on 15-2-27.
 */
@Component
public class SimplePackageHandlerMapping extends AbstractAnnotationHandlerMapping {

    @Override
    protected List<HandlerExecution> resolveExecutionChain(Object executor) {
        List<HandlerExecution> handlerExecutions = new ArrayList<>();

        //非null判断
        if (null == executor) {
            return handlerExecutions;
        }

        Method[] methods = ReflectionUtils.getAllDeclaredMethods(executor.getClass());

        //todo 减少变量
        for (Method method : methods) {
            if (!method.isAnnotationPresent(PackageDispatcherMapping.class)) {
                continue;
            }
            PackageDispatcherMapping packageDispatcherMapping = method.getAnnotation(PackageDispatcherMapping.class);
            //从注解中获取可能的注解
            List<String> patches = getPatchValue(packageDispatcherMapping);
            //增加execution
            for (String patch : patches) {
                HandlerExecution handlerExecution = new HandlerExecution(executor, method, patch);
                handlerExecutions.add(handlerExecution);
            }
        }

        return handlerExecutions;
    }

    private List<String> getPatchValue(PackageDispatcherMapping annotation) {
        //todo list 长度确定
        List<String> patches = new ArrayList<>();
        int messageType = annotation.messageType();
        int[] protocols = annotation.protocols();
        for (int protocol : protocols) {
            patches.add("" + messageType + "_" + protocol);
        }
        return patches;
    }

    public Object execute(int messageType, int protocol, ChannelHandlerContext ctx, ByteBuf msg) {
        String patch = "" + messageType + "_" + protocol;
        return execute(patch, ctx, msg);
    }

}
